/*
 * genHash.c
 *
 *  Created on: 20 May 2010
 *      Author: marco
 */

#include "genHash.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>//togliere poi


/**
 *
 * @param size
 * @param compare
 * @param copyk
 * @param copyp
 * @param hashfunction
 * @return
 */
hashTable_t * new_hashTable (unsigned int size,  int (* compare) (void *, void *), void* (* copyk) (void *),void* (*copyp) (void*),unsigned int (*hashfunction)(void*,unsigned int)){
	int i;
	hashTable_t *nht;

	nht = malloc(sizeof(hashTable_t));
	nht->compare = compare;
	nht->copyk = copyk;
	nht->copyp = copyp;
	nht->hash = hashfunction;
	nht->size = size;
	nht->table = (list_t**) malloc(size * sizeof(list_t *));
	for(i = 0; i < size; i++){
		nht->table[i] = NULL;
	}

	return nht;
}


/**
 *
 * @param key
 * @param size
 * @return
 */
unsigned int hash_int (void * key, unsigned int size){
	unsigned int index;
	index = abs( *(int*)key % size );
	if (index > size){
		printf("hash_int errore index!");
	}
	return index;
}


/**
 *
 * @param key
 * @param size
 * @return
 */
unsigned int hash_string (void * key, unsigned int size){
	unsigned int index;
	unsigned int tmp;
	tmp = *(int*)key;
	index =  abs( tmp % size);
	if (index > size){
		printf("hash_string errore index!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");

	}
	//printf("hash_string index =%d\n",index);
	return index;
}



/**
 *
 * @param pt
 */
void free_hashTable (hashTable_t ** pt){
	int i;
	int size;
	size = (*pt)->size;
	if(pt == NULL || *pt == NULL) { //necessario?
		return;
	}

	for(i = 0; i < size; i++){
		if( ((*pt)->table[i]) == NULL ) { //necessario?

		}
		else {
			free_List(&((*pt)->table[i]));
		}

	}

	free((*pt)->table);
	(*pt)->table = NULL;
//	free(*(pt)->compare);
//	free(*(pt)->copyk);
//	free(*(pt)->copyp);
//	free(*(pt)->hash);
//	free(pt->size);
	free(*pt);
	*pt = NULL;
}


/**
 *
 * @param t
 * @param key
 */
void * find_hashElement( hashTable_t * t,void * key ){
	int idx;
	void* res;
	elem_t* e;

	if(t == NULL){
		return NULL;
	}
	idx = t->hash(key,t->size);

	//non controlla se null perchè se find list element riceve null restistuisce null
	// \retval p puntatore a una \b copia del payload (alloca memoria)
//	return t->copyp((elem_t*)find_ListElement(t->table[idx],key)->payload);
	e = (elem_t*)find_ListElement(t->table[idx],key);
	if (e == NULL){
		return NULL;
	}
	res = t->copyp( e->payload );
	if (res == NULL){
		return NULL;
	}
	return res;
}


/**
 *
 * @param t
 * @param key
 * @param payload
 * @return
 */
int add_hashElement(hashTable_t * t,void * key, void* payload ){

	unsigned int idx;

	if(find_hashElement(t,key) != NULL){ //così però si chiama due volte la funz di hash
		return -1;
	}


	idx = t->hash(key,t->size);
	if(t->table[idx] == NULL){ // se non c'è ancora una lista all'indice idx la crea
		t->table[idx] = new_List(t->compare,t->copyk,t->copyp);
		//printf("dopo niu list!\n");

	}
	return add_ListElement(t->table[idx],key,payload);
}



/**
 *
 * @param t
 * @param key
 * @return
 */
int remove_hashElement( hashTable_t * t,void * key ) {

	unsigned int idx;
	idx = t->hash(key,t->size);
	return remove_ListElement(t->table[idx],key);
}














